A multi-tier system typically comprises one or more clients that are communicatively coupled to a server. Generally, a server is a combination of integrated software components and an allocation of computational resources, such as memory and processes for executing the integrated software components on a processor, where the combination of the software and computational resources are dedicated to providing a particular type of function on behalf of clients of the server. An example of server is a database server, which among other functions, manages and governs access to a database.
In order for a client to interact with a server, a server connection is established for the client. Through a server connection, the client can issue a series of requests to the server e.g. requests for data, such as queries.
For certain kinds of servers, server connections can be expensive to create and tear down. To take an example, a database server connection is a heavyweight resource that often is associated with a corresponding state (e.g., for authentication, SQL statements, etc.) on the database, and often comprises a dedicated process/thread of execution on the server side. Creating such a database server connection involves establishing a network transport connection from the client to the server machine, often spawning an operating system process/thread of execution, doing multiple roundtrips for authentication, and allocating some state associated with the connection. Tearing down such a connection involves disposing of the network transport connection and the associated state and the process/thread of execution. Thus, a server connection can be expensive to create and tear down. With a dedicated server model, a thread of execution and server connection state resources are dedicated to each server connection, and thus there is no sharing or persistence, and the thread of execution and the server connection state are recreated from scratch for each connection.
A “middle tier” generally refers to the processing that takes place in an application server that sits between the user's machine and a server such as a database server. The middle tier server performs the business logic. Some middle tiers implement server connection pooling so that multiple middle tier threads can share already opened connections and serially reuse them without having to create and tear down one for each web request, for example.
The foregoing scheme works when middle tiers are multi threaded. However, there are common scenarios in which middle tiers use single threaded processes. For example, PHP (Hypertext Preprocessor) is a very popular scripting language that is used in almost a third of the web domains, and PHP applications typically run in single threaded web server environments and often must access database servers to read and store data. There are also common scenarios in which a very large number of middle tier systems are implemented, with each middle tier system having small pools to the database. However, there is no way to share server connections across the pools, i.e., across the middle tier systems. In both of these scenarios, each process holds private resources associated with the database server that are not serially reusable by other processes and, therefore, are often idle. Hence, pooling from the middle tier does not work at all or does not work effectively enough.
Also note that the same scenario with reference to single threaded mid-tier systems is also possible in traditional client server systems where a large number of separate client processes hold onto server connections but need to use them relatively infrequently. In such cases also, pooling of such connections is desired but not possible without additional support. The present detailed description may refer to a mid-tier process operating on a server connection, but it should be understood as not being limited to processes belonging to middle tier application servers but also subsuming client-server systems as well.
One workaround may involve tearing down and recreating server connections, which is not a very viable alternative due to the significant overhead and resource usage involved, for example, in spawning a new thread of execution and recreating server connection state.
Another workaround could involve using a connection proxy to pool server connections among middle tier machines, through which all client processes interact with the back-end server for both requesting server connections as well as requesting server operations. Not only does such a middle tier architecture force an extra hop in all communications between the clients and the servers, i.e., through the proxy, but also often requires applications to be recoded to use the connection proxy's API (Application Programming Interface) rather than some standard API. Examples of such connection proxies include products such as SQL-Relay, that are used in PHP environments to alleviate some of the lack of server connection pooling.
Another workaround may involve the use of shared threads/processes on the server where the threads of execution can be shared amongst different server connections, but each server connection still has its distinct state in some shared memory accessible by all the threads. Moreover, in such a model, the dispatching process is always involved in the communications. Examples of such technologies include the Oracle Shared Server Database configuration with Oracle 11g.
The approaches described in this section are approaches that could be pursued, but not necessarily approaches that have been previously conceived or pursued. Therefore, unless otherwise indicated, it should not be assumed that any of the approaches described in this section qualify as prior art merely by virtue of their inclusion in this section.